#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

#include <stdio.h>
#include <string.h>

#define MSGSZ     128


typedef struct msgbuf {
	long    mtype;
	char    mtext[MSGSZ];
} message_buf;


int main(int arg,char **argv)
{

	int msqid,status,msqid2,j;
	key_t keyPF,keyFP;
	message_buf sbuf,rbuf;
	size_t buf_length;

	keyPF = 1234;
	keyFP = 4321;

	fprintf(stdout,"Processo Corrente %d \n",getpid());

	int retornoFork = fork();

	// PROCESSO PAI
	if (retornoFork>0){
		fprintf(stdout,"PID do processo pai %d \nPID do processo filho %d \n",getpid(),retornoFork);

		if ((msqid = msgget(keyPF, IPC_CREAT | 0666 )) < 0) {
			fprintf(stderr,"Erro ao abrir Caminho Pai para Filho");
			exit(1);
		}
		else{
			//fprintf(stdout,"Abriu Caminho de Pai para Filho %d", msqid);
		}

		sbuf.mtype = 1;
		strcpy(sbuf.mtext, "Mensagem do Pai");
		buf_length = strlen(sbuf.mtext) + 1 ;

		if (msgsnd(msqid, &sbuf, buf_length,IPC_NOWAIT) < 0) {
			printf ("Error %d, %d, %s, %d\n", msqid, sbuf.mtype, sbuf.mtext, buf_length);
			perror("msgsnd");
		}


		else{
			printf("Mensagem \"%s\" enviada\n", sbuf.mtext);
		}
		sleep(1);
		if ((msqid2 = msgget(keyFP,0666 )) < 0) {
			perror("msgget");
			exit(1);
		}
		//wait();
		if (msgrcv(msqid2, &rbuf, MSGSZ, 1,0) < 0) {
			printf("Não Recebeu de volta");
			exit(1);
		}
		else{
			fprintf(stdout,"Pai recebeu \"%s\" do filho \n",rbuf.mtext);

		}

		if (msgrcv(msqid2, &rbuf, MSGSZ, 1,0) < 0) {
			printf("Não Recebeu de volta");
			exit(1);
		}
		else{
			fprintf(stdout,"Pai recebeu \"%s\" do filho \n",rbuf.mtext);

		}
		wait();
		fprintf(stdout,"Pai aguardou o término do filho e agora vai encerar também \n");




	}



	// PROCESSO FILHO
	if (retornoFork==0){
		fprintf(stdout,"PID do processo corrente %d \nPID do processo pai %d\n",getpid(),getppid());

		if ((msqid = msgget(keyPF, 0666)) < 0) {
			perror("msgget");
			exit(1);
		}


		/*
		 * Receive an answer of message type 1.
		 */
		if (msgrcv(msqid, &rbuf, MSGSZ, 1, 0) < 0) {
			perror("msgrcv");
			exit(1);
		}

		fprintf(stdout,"O filho recebeu a mensagem \"%s\" \n", rbuf.mtext);

		strcpy(sbuf.mtext, "Mensagem do filho");

		if ((msqid2 = msgget(keyFP, IPC_CREAT | 0666 )) < 0) {
			perror("msgget");
			exit(1);
		}
		else{
			//fprintf(stdout,"msgget: msgget succeeded: msqid2 = %d\n", msqid2);
		}

		sbuf.mtype = 1;
		strcpy(sbuf.mtext, "Mensagem Do filho");
		buf_length = strlen(sbuf.mtext) + 1 ;

		if (msgsnd(msqid2, &sbuf, MSGSZ, IPC_NOWAIT) < 0) {
			printf ("%d, %d, %s, %d\n", msqid, sbuf.mtype, sbuf.mtext, buf_length);
			perror("msgsnd");
		}
		else{
			printf("Mensagem \"%s\" enviada pelo filho\n", sbuf.mtext);
		}
		for(j=0;j<10000;j++);
		sprintf(sbuf.mtext,"%d",j);
		//strcpy(sbuf.mtext,"Nova Mensagem do filho");

		if (msgsnd(msqid2, &sbuf, MSGSZ, IPC_NOWAIT) < 0) {
			printf ("%d, %d, %s, %d\n", msqid, sbuf.mtype, sbuf.mtext, buf_length);
			perror("msgsnd");
		}
		else{
			printf("Mensagem \"%s\" enviada pelo filho\n", sbuf.mtext);
		}
		execl("/bin/ls","ls",NULL);

		printf("Acabou o processo filho \n");
		exit(0);
	}


	//AMBOS PROCESSOS
	if(retornoFork!=0){
		fprintf(stdout,"Acabou o processo pai \n");
		exit(0);

	}
	return 0;
};
